package local.sumw3.findmydevices;

import java.util.List;

import local.sumw3.findmydeivces.R;
import local.sumw3.findmydevices.object.CommonConstants;
import local.sumw3.findmydevices.object.FindMyDevices;
import local.sumw3.findmydevices.object.bean.Device;
import local.sumw3.json.JSONException;
import android.app.ActionBar;
import android.app.ActionBar.OnNavigationListener;
import android.app.Activity;
import android.app.DialogFragment;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.FrameLayout;
import android.widget.Toast;

import com.baidu.mapapi.BMapManager;
import com.baidu.mapapi.map.MapController;
import com.baidu.mapapi.map.MapView;
import com.baidu.platform.comapi.basestruct.GeoPoint;

public class MainActivity extends Activity {

    private String userName_ = null;

    private String userPW_ = null;

    private FindMyDevices findDevice_ = null;

    private DeviceItemizedOverlay overlay_ = null;

    private int spinnerCount_ = 1;

    private int spinnerInitializedCount_ = 0;

    private ArrayAdapter<Device> deviceAdapter_ = null;

    private boolean isSendingMsg = false;

    private FrameLayout mMaskLayout = null;

    private BMapManager mBMapMan = null;

    private MapView mMapView = null;

    private ActionBar mActionBar = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        mBMapMan = new BMapManager(getApplication());
        mBMapMan.init("F0585A9AD3C7BBF4736E016EB4F421911206FDDD", null);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Bundle bundle = getIntent().getExtras();
        userName_ = bundle.getString(UIConstants.PA_LOGIN_USERNAME);
        userPW_ = bundle.getString(UIConstants.PA_LOGIN_USERPASSWORD);

        mActionBar = getActionBar();
        mActionBar.setDisplayHomeAsUpEnabled(true);
        mActionBar.setDisplayShowTitleEnabled(false);
        mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
        deviceAdapter_ = new ArrayAdapter<Device>(getBaseContext(), android.R.layout.simple_spinner_item);
        deviceAdapter_.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        OnNavigationListener mOnNavigationListener = new OnNavigationListener() {

            @Override
            public boolean onNavigationItemSelected(int arg0, long arg1) {
                if (spinnerInitializedCount_ < spinnerCount_) {
                    spinnerInitializedCount_++;
                } else {
                    updateMap();
                }
                return true;
            }

        };
        mActionBar.setListNavigationCallbacks(deviceAdapter_, mOnNavigationListener);

        mMaskLayout = (FrameLayout) findViewById(R.id.maskLayout);

        mMapView = (MapView) findViewById(R.id.mapView);
        mMapView.setBuiltInZoomControls(true);
        MapController mMapController = mMapView.getController();
        GeoPoint point = new GeoPoint((int) (39.915 * 1E6), (int) (116.404 * 1E6));
        mMapController.setCenter(point);
        mMapController.setZoom(12);

        UpdateTask task = new UpdateTask();
        task.execute();
    }

    private void updateMap() {
        List<Device> deviceList = findDevice_.getDeviceInfo();
        if (deviceList != null && deviceList.size() > 0) {
            Device currentDevice = deviceList.get(0);
            if (mActionBar.getNavigationItemCount() > 0 && mActionBar.getSelectedNavigationIndex() >= 0) {
                currentDevice = (Device) deviceAdapter_.getItem(mActionBar.getSelectedNavigationIndex());
            }

            // update map
            if (overlay_ == null) {
                Drawable marker = getResources().getDrawable(R.drawable.flagmarker);
                marker.setBounds(0, 0, 46, 46);
                overlay_ = new DeviceItemizedOverlay(marker, getBaseContext(), currentDevice);
            } else {
                overlay_.update(currentDevice);
            }
            mMapView.getOverlays().clear();
            mMapView.getOverlays().add(overlay_);
            mMapView.refresh();
            mMapView.getController().setZoom(16);
            mMapView.getController().animateTo(overlay_.getGeoPoint());
        } else {
            Log.i(this.getClass().toString(), getString(R.string.msg_noDeviceFound));
            Toast.makeText(getBaseContext(), getString(R.string.msg_noDeviceFound), Toast.LENGTH_LONG).show();
        }
    }

    private void updateSpinner() {
        List<Device> deviceList = findDevice_.getDeviceInfo();
        if (deviceList != null && deviceList.size() > 0) {
            deviceAdapter_.clear();
            for (Device device : deviceList) {
                deviceAdapter_.add(device);
            }
        }
    }

    class UpdateTask extends AsyncTask<Void, Void, String> {

        @Override
        protected void onPreExecute() {
            mMaskLayout.setVisibility(View.VISIBLE);
            super.onPreExecute();
        }

        @Override
        protected String doInBackground(Void... params) {
            try {
                if (findDevice_ == null) {
                    findDevice_ = new FindMyDevices(userName_, userPW_);
                }
                findDevice_.updateDevice();
            } catch (NullPointerException e) {
                Log.e(this.getClass().toString(), e.getMessage());
                return e.getMessage();
            } catch (IllegalArgumentException e) {
                Log.e(this.getClass().toString(), e.getMessage());
                return e.getMessage();
            } catch (JSONException e) {
                Log.e(this.getClass().toString(), e.getMessage());
            } catch (Exception e) {
                Log.e(this.getClass().toString(), e.getMessage());
                return e.getMessage();
            }
            return null;
        }

        @Override
        protected void onPostExecute(String msg) {
            mMaskLayout.setVisibility(View.INVISIBLE);
            if (msg != null && !"".equals(msg)) {
                if (msg.equals(CommonConstants.ERRORMSG_WRONGACESS)) {
                    Log.i(this.getClass().toString(), getString(R.string.msg_wrongAccess));
                    Toast.makeText(getBaseContext(), getString(R.string.msg_wrongAccess), Toast.LENGTH_LONG).show();
                } else {
                    Log.i(this.getClass().toString(), getString(R.string.msg_noLocationFound));
                    Toast.makeText(getBaseContext(), getString(R.string.msg_noLocationFound), Toast.LENGTH_LONG).show();
                }
            } else {
                updateSpinner();
                updateMap();
            }
        }

    }

    class MsgSendTask extends AsyncTask<String, Void, String> {

        @Override
        protected void onPreExecute() {
            isSendingMsg = true;
            super.onPreExecute();
        }

        @Override
        protected String doInBackground(String... params) {
            try {
                if (params == null || params.length < 3) {
                    throw new IllegalArgumentException(UIConstants.ERRORMSG_WRONGPARAM);
                }

                if (findDevice_ == null) {
                    findDevice_ = new FindMyDevices(userName_, userPW_);
                }
                findDevice_.sendMsg(params[0], true, params[1], params[2]);
            } catch (NullPointerException e) {
                Log.e(this.getClass().toString(), e.getMessage());
                return e.getMessage();
            } catch (IllegalArgumentException e) {
                Log.e(this.getClass().toString(), e.getMessage());
                return e.getMessage();
            } catch (JSONException e) {
                Log.e(this.getClass().toString(), e.getMessage());
            } catch (Exception e) {
                Log.e(this.getClass().toString(), e.getMessage());
                return e.getMessage();
            }
            return null;
        }

        @Override
        protected void onPostExecute(String msg) {
            if (msg != null && !"".equals(msg)) {
                Log.i(this.getClass().toString(), getString(R.string.msg_msgSendFailed));
                Toast.makeText(getBaseContext(), getString(R.string.msg_msgSendFailed), Toast.LENGTH_LONG).show();
            } else {
                Log.i(this.getClass().toString(), getString(R.string.msg_msgSendSucceeded));
                Toast.makeText(getBaseContext(), getString(R.string.msg_msgSendSucceeded), Toast.LENGTH_LONG).show();
            }
            isSendingMsg = false;
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case android.R.id.home:
            super.finish();
            break;

        case R.id.menu_refresh:
            UpdateTask task = new UpdateTask();
            task.execute();
            break;

        case R.id.menu_sendmsg:
            if (isSendingMsg) {
                Log.i(this.getClass().toString(), getString(R.string.msg_msgSendDuplicated));
                Toast.makeText(getBaseContext(), getString(R.string.msg_msgSendDuplicated), Toast.LENGTH_LONG).show();
            } else {
                FragmentTransaction ft = getFragmentManager().beginTransaction();
                Fragment prev = getFragmentManager().findFragmentByTag(UIConstants.FRAGMENT_TAG_MAINACTIVITY);
                if (prev != null) {
                    ft.remove(prev);
                }
                ft.addToBackStack(null);
                MsgSendFragment newFragment = MsgSendFragment.newInstance();
                newFragment.show(ft, UIConstants.FRAGMENT_TAG_MAINACTIVITY);
            }
            break;

        case R.id.menu_console:
            FragmentTransaction ft = getFragmentManager().beginTransaction();
            Fragment prev = getFragmentManager().findFragmentByTag(UIConstants.FRAGMENT_TAG_MAINACTIVITY);
            if (prev != null) {
                ft.remove(prev);
            }
            ft.addToBackStack(null);
            DialogFragment newFragment = ConsoleFragment.newInstance();
            newFragment.show(ft, UIConstants.FRAGMENT_TAG_MAINACTIVITY);
            break;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    protected void onDestroy() {
        mMapView.destroy();
        if (mBMapMan != null) {
            mBMapMan.destroy();
            mBMapMan = null;
        }
        super.onDestroy();
    }

    @Override
    protected void onPause() {
        mMapView.onPause();
        if (mBMapMan != null) {
            mBMapMan.stop();
        }
        super.onPause();
    }

    @Override
    protected void onResume() {
        mMapView.onResume();
        if (mBMapMan != null) {
            mBMapMan.start();
        }
        super.onResume();
    }

    protected FindMyDevices getFindDevice() {
        return findDevice_;
    }

    protected void sendMsg(String title, String content) {
        Device currentDevice = null;
        if (mActionBar.getNavigationItemCount() > 0 && mActionBar.getSelectedNavigationIndex() >= 0) {
            currentDevice = (Device) deviceAdapter_.getItem(mActionBar.getSelectedNavigationIndex());
        } else {
            List<Device> deviceList = findDevice_.getDeviceInfo();
            if (deviceList != null && deviceList.size() > 0) {
                currentDevice = deviceList.get(0);
            }
        }
        if (currentDevice != null) {
            MsgSendTask task = new MsgSendTask();
            task.execute(currentDevice.getId(), title, content);
        } else {
            Log.i(this.getClass().toString(), getString(R.string.msg_noDeviceFound));
            Toast.makeText(getBaseContext(), getString(R.string.msg_noDeviceFound), Toast.LENGTH_LONG).show();
        }
    }
}
